import threading
import requests
from common.logger import logger
import time
from concurrent.futures import ThreadPoolExecutor, TimeoutError
import re
import datetime
from database.proxy_pool_table import ProxyPoolTable

class ProxyManager:

    def __init__(self, shared_proxy) -> None:
        self.__interval = shared_proxy['interval']
        self.__type = shared_proxy['type']
        self.__url = shared_proxy['url']
        self.__fetch_count = shared_proxy['fetch_count']

    def proxy_type(self) -> str:
        return self.__type

    def update_time(self):
        with ProxyPoolTable() as db:
            t = db.expired_time(self.__type, 0)
            if t:
                return t.strftime("%Y-%m-%d %H:%M:%S")
        return None

    def active(self) -> None:
        threading.Timer(1, self.__fetch_proxy).start()
        
    def get_all_proxy(self):
        with ProxyPoolTable() as db:
            return db.fetchall(self.__type)
        
    def __fetch_proxy_ips(self):
        ips = []
        try:
            rsp = requests.get(self.__url, timeout=30)
            ipRows = rsp.text.split()
            for row in ipRows:
                ip = row.strip()
                # 判断ip是格式 xxx.xxx.xxx.xxx:xxxx
                if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d+$", ip):
                    ips.append(ip)
            if len(ipRows) < 3:
                logger.error(f"获取代理失败: {rsp.text}")
                return []
            count = len(ips)
            ips = list(set(ips))
            logger.success(f"获取代理成功，去重前: {count}，去重后: {len(ips)}")
        except Exception as e:
            logger.error(f"获取代理失败: {repr(e)}")
            
        return ips
            
    def __fetch_proxy(self):
        try:
            logger.info(f"开始获取代理...")
            ips = []
            for i in range(self.__fetch_count):
                ips.extend(self.__fetch_proxy_ips())
                time.sleep(3)
            count = len(ips)
            ips = list(set(ips))
            logger.success(f"获取代理完成，去重前 {count} 条, 去重后 {len(ips)} 条")
            
            if len(ips) > 0:
                with ProxyPoolTable() as db:
                    db.clear(self.__type)
                    db.insert(ips, self.__type)
                    db.commit()
            
        except Exception as e:
            logger.exception(e)
        
        threading.Timer(self.__interval, self.__fetch_proxy).start()
